/**
* All Rights Reserved , Copyright (C) 2021 , 青岛鼎信通讯股份有限公司
*
* MpmProjectTaskService
* 项目任务
*
* 修改纪录
* 2021-01-07 版本：1.0 lanjianwei 创建。
* @version 版本：1.0
* @author 作者：lanjianwei
* 创建日期：2021-01-07
*/
package com.topscomm.mpm.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.topscomm.basic.util.SQLAdapter;
import com.topscomm.cbo.model.TreeModel;
import com.topscomm.cbo.pojo.CboApprovalNodeInsEntity;
import com.topscomm.cbo.pojo.CboUserEntity;
import com.topscomm.cbo.service.ICboMessageAppService;
import com.topscomm.cbo.service.ICboMessageSysService;
import com.topscomm.cbo.service.impl.CboUserService;
import com.topscomm.mpm.MpmSystemConst;
import com.topscomm.mpm.pojo.*;
import com.topscomm.mpm.utils.ConvertTimeUtil;
import com.topscomm.mpm.utils.MessageUtil;
import com.topscomm.pub.util.StringBufferProxy;
import com.topscomm.tap.common.DatacodeCache;
import com.topscomm.tap.common.ParameterCache;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import lombok.SneakyThrows;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import com.topscomm.basic.BasicEntity;
import com.topscomm.basic.exception.ServiceException;
import com.topscomm.basic.util.PrimaryKeyUtil;
import com.topscomm.mis.pojo.MisDeptArchEntity;
import com.topscomm.mpm.service.IMpmProjectTaskService;
import com.topscomm.mpm.service.impl.auto.MpmProjectTaskServiceAuto;
import com.topscomm.pub.util.ConvertUtil;
import com.topscomm.pub.util.StringUtil;
import com.topscomm.pub.vo.ResponseResult;
import com.topscomm.tap.TapEntity;
import com.topscomm.tap.common.FlowDatacodeCache;
import com.topscomm.tap.common.SessionUserBean;
import org.springframework.transaction.annotation.Transactional;
import sun.java2d.pipe.SpanShapeRenderer;

@Service(value = "mpmProjectTaskService")
@Scope(value = "singleton")
public class MpmProjectTaskService extends MpmProjectTaskServiceAuto implements IMpmProjectTaskService {
    FlowDatacodeCache flowDatacodeCache = new FlowDatacodeCache();
    protected List<Map<String, Object>> flowidList = new ArrayList();
	@Resource(name = "mpmProjectTaskTemplateService")
	private MpmProjectTaskTemplateService mpmProjectTaskTemplateService;
	@Autowired
	private MpmProjectMilepostService mpmProjectMilepostService;
	@Autowired
	private MpmProjectService mpmProjectService;
	@Autowired
	private DatacodeCache datacodeCache;
	@Autowired
	private ICboMessageAppService cboMessageAppService;
	@Autowired
	private ICboMessageSysService cboMessageSysService;
	@Autowired
	private CboUserService cboUserService;
	@Autowired
	private MpmProjectPlanService mpmProjectPlanService;
	@Autowired
	private MpmProjectFishFirstService mpmProjectFishFirstService;
	@Autowired
	private MpmProjectFishSecondService mpmProjectFishSecondService;
	@Autowired
	private MpmProjectSquaredService mpmProjectSquaredService;
	@Autowired
	private MpmProjectTaskFeedbackService mpmProjectTaskFeedbackService;
	@Autowired
	private MpmProjectTaskCloseService mpmProjectTaskCloseService;
	@Autowired
	private MpmProjectSaleService mpmProjectSaleService;
	private static final Logger log= LoggerFactory.getLogger(MpmProjectTaskService.class);
	/**
	 * @author: lanjianwei
	 * @date: 2021-01-07
	 * @param entity
	 * @throws ServiceException
	 * @description:单号生成
	 * @modify:
	 */
	@Override
	protected void beforeInsert(BasicEntity entity){
		super.beforeInsert(entity);
		if (haveSystemTask(entity)) {
			throw new ServiceException("策划中该任务名称已存在，请确认!");
		}
		if (entity.getId() <= 0) {// 赋值Id和单号
			long[] arrayId = PrimaryKeyUtil.GeneIDs(entity.getTableName(), 1);
			entity.setId(arrayId[0]);
			String docNo = String.valueOf(arrayId[0]);
			docNo = docNo.substring(0, 6) + docNo.substring(9);
			entity.setValue(MpmProjectTaskEntity.FieldDocno, docNo);
			// 当里程碑及任务的状态为达成，但是新增了任务，此时把里程碑及任务的状态更改为未达成
			StringBufferProxy sql = new StringBufferProxy();
			sql.appendSingle(" {0} = '{1}'  and  {2} = 1 ", MpmProjectMilepostEntity.FieldOperatecode,
					ConvertUtil.convertToString(entity.getValue(MpmProjectTaskEntity.FieldMilepostcode)), MpmProjectMilepostEntity.FieldEnabled);
			MpmProjectMilepostEntity mpmProjectMilepostEntity = mpmProjectMilepostService.queryObjectByWhere(sql.toString());
			if (ObjectUtil.isEmpty(mpmProjectMilepostEntity)) {
				sql.clear();
				sql.appendSingle(" {0} = '{1}' order by {2} desc ", MpmProjectMilepostEntity.FieldOperatecode, ConvertUtil.convertToString(entity.getValue(MpmProjectTaskEntity.FieldMilepostcode)),
						MpmProjectMilepostEntity.FieldCreateon);
				mpmProjectMilepostEntity = mpmProjectMilepostService.queryByWhere(sql.toString()).get(0);
			}
			if(1 == mpmProjectMilepostEntity.getMilepoststate()) {
				mpmProjectMilepostEntity.setMilepoststate(0);
				mpmProjectMilepostEntity.setActualfinishtime(null);
				mpmProjectMilepostService.updateEntity(mpmProjectMilepostEntity);
			}
		}
		// 当用户填写了更新频次，为更新时间赋值
		if (!ObjectUtil.isEmpty(entity.getValue("taskupdatefre"))) {
			entity.setValue("taskupdatedate", new Date());
		}
	}


	/***
	 * @description: 判断日期是否准确
	 * @param date
	 * @return
	 * @author: jiangtao1
	 * @date: 2021/12/2 9:49
	 * @modify:
	 */
	private boolean checkDateRight(Date date) {
        boolean dateIsRight = true;
	    //按照任务模板添加时，任务的计划开始时间和计划完成时间都为空，排除这种情况
	    if(date == null) {
			return dateIsRight;
		}
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
	    String dateString = simpleDateFormat.format(date);
		try {
			if (date == simpleDateFormat.parse(dateString)) {
                dateIsRight = false;
            }
			return dateIsRight;
		} catch (ParseException e) {
			e.printStackTrace();
			return false;
		}
	}

	@SneakyThrows
	@Override
	protected void updateBefore(Map<String, Object> map) throws ServiceException {
		super.updateBefore(map);
		MpmProjectTaskEntity mpmProjectTaskEntity = new MpmProjectTaskEntity();
		mpmProjectTaskEntity.convertFromMap(map);
		// 如果是从项目任务页面更新的任务，需要校验计划完成日期，不能早于里程碑及任务的计划完成日期
		if (map.containsKey("fromindex")) {
			StringBufferProxy sql = new StringBufferProxy();
			sql.appendSingle("{0} = {1} and enabled = 1 ", MpmProjectMilepostEntity.FieldOperatecode, ConvertUtil.convertToString(map.get("milepostcode")));
			List<MpmProjectMilepostEntity> mpmProjectMilepostEntityList = mpmProjectMilepostService.queryByWhere(sql.toString());
			if (CollectionUtil.isEmpty(mpmProjectMilepostEntityList)) {
				throw new ServiceException("未找到任务对应的里程碑及任务，请在策划审批结束后修改！");
			}
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			Date milepostDate = mpmProjectMilepostEntityList.get(0).getPlanfinishtime();
			Date taskDate = sdf.parse(ConvertUtil.convertToString(map.get("planenddate")));
			if (taskDate.compareTo(milepostDate)>0) {
				throw new ServiceException("任务的计划完成日期不能大于所属里程碑及任务的计划达成日期！");
			}
		}
		// 当用户填写了更新频次，为更新时间赋值,差距与改进/任务反馈完成需更新taskupdatedate字段，不清除此字段
		if (!(ConvertUtil.convertToInt(map.get("dateupdateflag")) == 1)) {
			map.remove("taskupdatedate");
		}
		MpmProjectTaskEntity originEntity = this.queryById(ConvertUtil.convertToString(map.get("id")));
		String newfre = ConvertUtil.convertToString(map.get("taskupdatefre"));
		String oldfre = ConvertUtil.convertToString(originEntity.getTaskupdatefre());
		if (!StringUtil.isEmpty(newfre) && !oldfre.equals(newfre) && "9".equals(ConvertUtil.convertToString(map.get("state")))) {
			map.put("taskupdatedate", new Date());
		}
		// 如果是复制后未修改的进行判断查看是否修改
		if(ConvertUtil.convertToString(MpmSystemConst.EnableEnum.Unenabled).equals(map.get(MpmProjectTaskEntity.FieldCopyedit))) {
		    //定义比较的字段
			List<String> compareFields = Arrays.asList(MpmProjectTaskEntity.FieldTasktarget,MpmProjectTaskEntity.FieldTaskdetail,MpmProjectTaskEntity.FieldTaskname);
			//获取复制源头信息
			Map<String,Object> copyFromMap = this.queryMapById(ConvertUtil.convertToString(map.get(MpmProjectTaskEntity.FieldCopysourceid)));
			boolean isSame = true;
			//进行比较
			for(String field : compareFields) {
				if(!(ConvertUtil.convertToString(copyFromMap.get(field)).equals(ConvertUtil.convertToString(map.get(field))))){
					isSame = false;
					break;
				}
			}
			// 如果不相同，更新copyedit
			if (!isSame) {
				map.put(MpmProjectTaskEntity.FieldCopyedit, ConvertUtil.convertToString(MpmSystemConst.EnableEnum.Enabled));
			}
		}
		// 如果是不走审批单独变更一个任务(map中存有fromindex标记)，直接发送变更信息
		this.singleChangeTaskSendMessage(map);

		// 暂时去掉updatebefore的重复任务校验，防止老数据存在导致任务反馈报错
//		if (haveSystemTask(mpmProjectTaskEntity)) {
//			throw new ServiceException("策划中该任务名称已存在，请确认!");
//		}
//		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
//		StringBufferProxy sql = new StringBufferProxy();
//		sql.appendSingle("operatecode = '{0}'  and  enabled=1",map.get("milepostcode"));
//		List<MpmProjectMilepostEntity> mpmProjectMilepostEntityList = mpmProjectMilepostService
//			.queryByWhere(sql.toString());
//		if(mpmProjectMilepostEntityList.size()==0) {
//			sql.clear();
//			sql.appendSingle("operatecode = '{0}'",map.get("milepostcode"));
//			mpmProjectMilepostEntityList = mpmProjectMilepostService
//				.queryByWhere(sql.toString());
//		}
//		Date planfinishtime = mpmProjectMilepostEntityList.get(0).getPlanfinishtime();
//		Date planstartdate=null;
//		Date planenddate =null;
//		try {
//			 planstartdate = simpleDateFormat.parse(map.get("planstartdate").toString());
//			 planenddate = simpleDateFormat.parse(map.get("planenddate").toString());
//		} catch (ParseException e) {
//			e.printStackTrace();
//		}
//		SimpleDateFormat simple1= new SimpleDateFormat("yyyy-MM-dd 00:00:00");
//		String format = simple1.format(new Date());
//		Date dateNow=null;
//		try {
//			dateNow = simple1.parse(format);
//		} catch (ParseException e) {
//			e.printStackTrace();
//
//		}
//		String mpm_taskPlanDate_limit = ParameterCache.getValue("Mpm_TaskPlanDate_Limit");
//		if("1".equals(mpm_taskPlanDate_limit)){
//			if(planstartdate.compareTo(dateNow)<0){
//				throw new MessageException("任务的计划开始日期不能小于今天！");
//			}
//		}
//		if(planenddate.compareTo(planfinishtime)>0){
//			throw new MessageException("任务的计划完成日期不能大于所属里程碑及任务的计划达成日期！");
//		}
//		if(planstartdate.compareTo(planenddate)>0){
//			throw new MessageException("任务的计划开始日期不能大于计划完成日期！");
//		}

	}
	/**
     * @Title: beforeSubmit
     * @description:
     * @param entity
     * @param sessionUserBean
     * @author: lanjianwei
     * @date: 2021年1月7日下午8:12:55
     * @modify:
    */
    @Override
    protected void beforeSubmit(TapEntity entity, SessionUserBean sessionUserBean) {
        super.beforeSubmit(entity, sessionUserBean);
        MpmProjectTaskEntity mpmProjectTaskEntity= (MpmProjectTaskEntity) entity;
        mpmProjectTaskEntity.setTaskdistributedate(new Date());
        this.flowidList = flowDatacodeCache.getApprovalFlowListMap("ApprovalFlow_MpmProjectTask",
        		mpmProjectTaskEntity.getApplyusercode(), "sortcode");
        if (flowidList.size() > 0) {// 赋值审批流程id
        	mpmProjectTaskEntity.setFlowid(ConvertUtil.convertToLong(flowidList.get(0).get("id")));
        } else {
            throw new ServiceException("没有匹配的审批流，请联系管理员！");
        }
    }

	/**
	 * @Title: insert
	 * @description:按项目插入任务
	 * @param paraMap
	 * @return
	 * @author: lanjianwei
	 * @date: 2021年1月12日下午5:25:05
	 * @modify:
	*/
	public ResponseResult insertFromProject(Map<String, Object> paraMap) {
		String projectcodeNew=(String)paraMap.get("projectcodenew");
		String projectnameNew=(String)paraMap.get("projectnamenew");
		String ids=(String)paraMap.get("keys");
		List<BasicEntity> insertList = new ArrayList<BasicEntity>();
		if(!StringUtil.isEmpty(ids)) {
			List<MpmProjectTaskEntity>  mpmProjectTaskEntities=this.queryByIds(ids);
			for (MpmProjectTaskEntity mpmProjectTaskEntity : mpmProjectTaskEntities) {
				mpmProjectTaskEntity = this.insertTaskEntity(mpmProjectTaskEntity,projectcodeNew,projectnameNew);
				insertList.add(mpmProjectTaskEntity);
			}
			if(insertList.size()> 0) {
				this.insertBatch(insertList);
			}
			return ResponseResult.ok("插入任务成功，共 "+ mpmProjectTaskEntities.size() +"条。");
		}else {
		   return ResponseResult.ok("没有可插入的任务数据，请确认勾选相关任务！");
		}
	}

	/***
	 * @description: 任务实体赋值
	 * @param mpmProjectTaskEntity
	 * @param projectcodeNew
	 * @param projectnameNew
	 * @return
	 * @author: jiangtao1
	 * @date: 2021/12/2 13:39
	 * @modify:
	 */
	private MpmProjectTaskEntity insertTaskEntity(MpmProjectTaskEntity mpmProjectTaskEntity, String projectcodeNew, String projectnameNew) {
		//赋值任务初始字段
		mpmProjectTaskEntity.setId(0);
		mpmProjectTaskEntity.setTaskstate("0");
		mpmProjectTaskEntity.setState(0);
		mpmProjectTaskEntity.setLatestphase("");
		mpmProjectTaskEntity.setDocno("");
		mpmProjectTaskEntity.setDocdate(new Date());
		mpmProjectTaskEntity.setTaskschedule("0");
		mpmProjectTaskEntity.setMilepostcode("0");
		mpmProjectTaskEntity.setMilepostname("");
		mpmProjectTaskEntity.setProjectcode(projectcodeNew);
		mpmProjectTaskEntity.setProjectname(projectnameNew);
		mpmProjectTaskEntity.setActualstartdate(null);
		mpmProjectTaskEntity.setActualenddate(null);
		mpmProjectTaskEntity.setApplyorgcode(this.getSessionUserBean().getOrg().getCode());
		mpmProjectTaskEntity.setApplydeptcode(this.getSessionUserBean().getDept().getCode());
		mpmProjectTaskEntity.setOrgcode(this.getSessionUserBean().getOrg().getCode());
		mpmProjectTaskEntity.setDeptcode(this.getSessionUserBean().getDept().getCode());
		mpmProjectTaskEntity.setUsercode(this.getSessionUserBean().getUser().getCode());
		mpmProjectTaskEntity.setUsername(this.getSessionUserBean().getUser().getName());
		mpmProjectTaskEntity.setApplyusercode(this.getSessionUserBean().getUser().getCode());
		mpmProjectTaskEntity.setApplyusername(this.getSessionUserBean().getUser().getName());
		return mpmProjectTaskEntity;
	}
	/**
	 * @Title: insertFromTaskTemplate
	 * @description:按模板插入任务
	 * @param paraMap
	 * @return
	 * @author: lanjianwei
	 * @date: 2021年1月14日下午3:55:21
	 * @modify:
	*/
	public ResponseResult insertFromTaskTemplate(Map<String, Object> paraMap) {
		String projectcodeNew=(String)paraMap.get("projectcodenew");
		String projectnameNew=(String)paraMap.get("projectnamenew");
		String ids=(String)paraMap.get("keys");
		List<BasicEntity> insertList = new ArrayList<BasicEntity>();
		if(!StringUtil.isEmpty(ids)) {
			List<MpmProjectTaskTemplateEntity>  mpmProjectTaskTemplateEntities=mpmProjectTaskTemplateService.queryByIds(ids);
			for (MpmProjectTaskTemplateEntity mpmProjectTaskTemplateEntity : mpmProjectTaskTemplateEntities) {
				MpmProjectTaskEntity mpmProjectTaskEntity=new MpmProjectTaskEntity();
				//赋值任务初始字段
				mpmProjectTaskEntity = this.insertTaskEntity(mpmProjectTaskEntity,projectcodeNew,projectnameNew);
				//赋值拷贝字段
				mpmProjectTaskEntity.setTaskdetail(mpmProjectTaskTemplateEntity.getTaskdetail());
				mpmProjectTaskEntity.setTaskname(mpmProjectTaskTemplateEntity.getTaskname());
				mpmProjectTaskEntity.setTaskpriority(mpmProjectTaskTemplateEntity.getTaskpriority());
				mpmProjectTaskEntity.setTasktype(mpmProjectTaskTemplateEntity.getTasktype());
				mpmProjectTaskEntity.setTaskschedule("0");
				mpmProjectTaskEntity.setTaskexplain(mpmProjectTaskTemplateEntity.getTaskexplain());
				mpmProjectTaskEntity.setIstemplate("1");
				mpmProjectTaskEntity.setTasktemplateid(mpmProjectTaskTemplateEntity.getId());
				insertList.add(mpmProjectTaskEntity);
			}
			if(insertList.size()> 0) {
				this.insertBatch(insertList);
			}
			return ResponseResult.ok("插入任务成功，共 "+ mpmProjectTaskTemplateEntities.size() +"条。");
		}else {
			return ResponseResult.ok("没有可插入的任务数据，请确认勾选相关任务！");
		}
	}

	/**
	 * @Title: startTask
	 * @description:开始任务
	 * @param paraMap
	 * @return
	 * @author: lanjianwei
	 * @date: 2021年1月14日下午6:21:38
	 * @modify:
	*/
	public ResponseResult startTask(Map<String, Object> paraMap) {
		String ids=String.valueOf(paraMap.get("ids"));
		if(!StringUtil.isEmpty(ids)) {
			List<MpmProjectTaskEntity>  mpmProjectTaskEntities=this.queryByIds(ids);
			List<BasicEntity> updateList = new ArrayList<BasicEntity>();
			for (MpmProjectTaskEntity mpmProjectTaskEntity : mpmProjectTaskEntities) {
				mpmProjectTaskEntity.setTaskstate("1");
				SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
				try {
					String actualstartdate = ConvertUtil.convertToString(paraMap.get("actualstartdate"));
					if(!StringUtil.isEmpty(actualstartdate)) {
						mpmProjectTaskEntity.setActualstartdate(simpleDateFormat.parse(actualstartdate));
					} else {
						mpmProjectTaskEntity.setActualstartdate(new Date());
					}
				} catch (ParseException e) {
					log.error("任务的实际开始时间转换出错:"+e);
					return ResponseResult.error("开始任务失败，请联系管理员");
				}
				updateList.add(mpmProjectTaskEntity);
			}
			if(updateList.size()>0) {
				this.updateBatch(updateList);
			}
			return ResponseResult.ok("成功开始任务");
		}else {
			return ResponseResult.ok("没有可开始的任务，请确认勾选相关任务！");
		}
	}

//	public ResponseResult startTask(Map<String, Object> paraMap) {
//		String ids=String.valueOf(paraMap.get("ids"));
//		if(!StringUtil.isEmpty(ids)) {
//			List<MpmProjectTaskEntity>  mpmProjectTaskEntities=this.queryByIds(ids);
//			for (MpmProjectTaskEntity mpmProjectTaskEntity : mpmProjectTaskEntities) {
//				mpmProjectTaskEntity.setTaskstate("1");
//				mpmProjectTaskEntity.setActualstartdate(new Date());
//				this.updateEntity(mpmProjectTaskEntity);
//			}
//			return ResponseResult.ok("成功开始任务");
//		}else {
//			return ResponseResult.ok("没有可开始的任务，请确认勾选相关任务！");
//		}
//	}
	/**
	 * @Title: deleteBefore
	 * @description: 任务删除时判断对应的里程碑及任务是否可以变为已达成
	 * @param whereSql
	 * @return
	 * @author: houyuhang
	 * @date: 2021年11月12日
	 * @modify:
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	protected void deleteBefore(String whereSql) {
		super.deleteBefore(whereSql);
		//找到删除的一条或多条任务
		List<MpmProjectTaskEntity> mpmProjectTaskEntities = this.queryByWhere(whereSql);
		if (CollectionUtil.isEmpty(mpmProjectTaskEntities)) {
			return;
		}
		// 如果删除了任务，需要同步删除任务关联的鱼骨图和九宫格
		String taskStr = mpmProjectTaskEntities.stream().map(item -> ConvertUtil.convertToString(item.getId())).collect(Collectors.joining(","));
		StringBufferProxy sqltask = new StringBufferProxy();
		sqltask.appendSingle(" taskid in ({0}) ", taskStr);
		mpmProjectFishFirstService.deleteByWhere(sqltask.toString());
		mpmProjectFishSecondService.deleteByWhere(sqltask.toString());
		mpmProjectSquaredService.deleteByWhere(sqltask.toString());
		// 如果删除任务的状态不为未开始（A级、春秋季攻势、项目经理为省总删除任务），则级联删除
		this.deleteCascadeTask(mpmProjectTaskEntities);
		// 删除这个任务后，其他任务都完成或关闭，这时要将里程碑及任务的状态置为已完成
		List<String> updateListCodes = new ArrayList<String>();
		StringBufferProxy sql = new StringBufferProxy();
		for(MpmProjectTaskEntity mpmProjectTaskEntity : mpmProjectTaskEntities) {
			sql.clear();
			sql.appendSingle(" milepostcode = '{0}' and id != '{1}' ",mpmProjectTaskEntity.getMilepostcode(),mpmProjectTaskEntity.getId());
			List<MpmProjectTaskEntity> mpmProjectTaskEntitiesExtra = this.queryByWhere(sql.toString());
			if(CollectionUtil.isEmpty(mpmProjectTaskEntitiesExtra)) {
				continue;
			}
			boolean flag = true;
			for(MpmProjectTaskEntity mpmProjectTaskEntity1 : mpmProjectTaskEntitiesExtra) {
				// 该里程碑及任务下的其他任务为未开始或进行中状态，里程碑及任务状态不改变
				if(MpmSystemConst.TaskStateCode.TaskNotStartCode.equals(mpmProjectTaskEntity1.getTaskstate()) ||
						MpmSystemConst.TaskStateCode.TaskIncompleteCode.equals(mpmProjectTaskEntity1.getTaskstate())) {
					flag = false;
					break;
				}
			}
			// 删除这个任务后，其他任务都完成或关闭，这时要将里程碑及任务的状态置为已完成
			if(flag) {
				updateListCodes.add(mpmProjectTaskEntity.getMilepostcode());
			}
		}
		if(updateListCodes.size()==0) {
			return;
		}
		String updaCodes = updateListCodes.stream().collect(Collectors.joining("','","'","'"));
		List<BasicEntity> updateList = new ArrayList<>();
		sql.clear();
		sql.appendSingle(" operatecode in ({0})  and milepoststate = '0' and enabled = 1",updaCodes);
		List<MpmProjectMilepostEntity> milepostEntities = mpmProjectMilepostService.queryByWhere(sql.toString());
		for(MpmProjectMilepostEntity milepostEntity:milepostEntities) {
			milepostEntity.setMilepoststate(1);
			milepostEntity.setActualfinishtime(new Date());
			updateList.add(milepostEntity);
		}
		if(updateList.size()>0) {
			mpmProjectMilepostService.updateBatch(updateList);
		}
	}
	/**
	 * @Title: generateTaskcode
	 * @description: 生成任务编号
	 * @param tempList
	 * @return
	 * @author: houyuhang
	 * @date: 2021年11月22日
	 * @modify:
	 */
	public List<Map<String, Object>> generateTaskcode(List<Map<String, Object>> tempList, Map<String, Object> paraMap) {
		// 查找最近一次策划书
		StringBufferProxy sql = new StringBufferProxy();
		sql.appendSingle("projectcode = '{0}' order by createon desc ", tempList.get(0).get("projectcode"));
		List<MpmProjectPlanEntity> mpmProjectPlanEntities = mpmProjectPlanService.queryByWhere(sql.toString());
		if (CollectionUtil.isEmpty(mpmProjectPlanEntities)) {
			return new ArrayList<>();
		}
		// 查找最近一次策划书对应的里程碑
		sql.clear();
		sql.appendSingle(" planid = '{0}' order by sortcode asc,planfinishtime asc,id asc ", mpmProjectPlanEntities.get(0).getId());
		List<MpmProjectMilepostEntity> mpmProjectMilepostEntityList = mpmProjectMilepostService.queryByWhere(sql.toString());
		// 将任务按照milepostcode进行分类
		Map<String, List<Map<String, Object>>> mpmProjectTaskEntityMap = tempList.stream().collect(Collectors.groupingBy(item -> ConvertUtil.convertToString(item.get("milepostcode"))));
		List<Map<String, Object>> milepostList = new ArrayList<>();
		int count = 1;
		for (MpmProjectMilepostEntity mpmProjectMilepostEntity : mpmProjectMilepostEntityList) {
			Map<String, Object> dataMap = new HashMap<>();
			dataMap.put("milepostcode", mpmProjectMilepostEntity.getOperatecode());
			dataMap.put("milepostindex", count);
			dataMap.put("taskindex", 1);
			milepostList.add(dataMap);
			count++;
		}
		List<Map<String, Object>> resList = new ArrayList<>();
		// 遍历所有里程碑，为任务增加任务编号
		for (Map<String, Object> milepost : milepostList) {
			List<Map<String, Object>> taskList = mpmProjectTaskEntityMap.get(ConvertUtil.convertToString(milepost.get("milepostcode")));
			if (CollectionUtil.isEmpty(taskList)) {
				continue;
			}
			int countTask = 1;
			for (Map<String, Object> task : taskList) {
				task.put("generatetaskcode", ConvertUtil.convertToString(milepost.get("milepostindex")) + '-' + ConvertUtil.convertToString(countTask));
				countTask++;
				resList.add(task);
			}
		}
		if (!ObjectUtil.isEmpty(paraMap.get("sidx")) && !"generatetaskcode".equals(paraMap.get("sidx"))) {
			String sidx = ConvertUtil.convertToString(paraMap.get("sidx"));
			String sord = ConvertUtil.convertToString(paraMap.get("sord"));
			if ("asc".equals(sord)) {
				resList.sort(Comparator.comparing(item -> ConvertUtil.convertToString(item.get(sidx)), Comparator.naturalOrder()));
			} else {
				resList.sort(Comparator.comparing(item -> ConvertUtil.convertToString(item.get(sidx)), Comparator.reverseOrder()));
			}
		}
		if (!ObjectUtil.isEmpty(paraMap.get("sidx")) && "generatetaskcode".equals(paraMap.get("sidx")) && "desc".equals(paraMap.get("sord"))) {
			Collections.reverse(resList);
		}
		return resList;
	}
	/**
	 * @Title: queryOverdueTask
	 * @description: 查询任务超期信息
	 * @param paraMap
	 * @return
	 * @author: houyuhang
	 * @date: 2021年12月1日
	 * @modify:
	 */
	@Override
	public Map<String,Object> queryOverdueTask(Map<String, Object> paraMap) {
		Map<String, Object> overdueProjectTaskResult = new HashMap<>();
		StringBufferProxy sql = new StringBufferProxy();
		sql.appendSingle(" MpmProjectTask.PLANENDDATE<  {0}  and MpmProjectTask.state=9 and " +
						"MpmProjectTask.taskstate in ('{1}','{2}') ",
				SQLAdapter.toDateShort(DateUtil.formatDate(new Date())), MpmSystemConst.TaskStateCode.TaskNotStartCode,
				MpmSystemConst.TaskStateCode.TaskIncompleteCode);
		sql.appendSingle(" and {0} ", mpmProjectService.whereExistsSqlForIndex(MpmProjectTaskEntity.tableName,
				MpmProjectTaskEntity.FieldProjectcode, ConvertUtil.convertToString(paraMap.get("dataPermissionFlag"))));
		int countTask = this.getCount(sql.toString());
		overdueProjectTaskResult.put("code", "overdueProjectTaskNum");
		overdueProjectTaskResult.put("name", "超期任务");
		overdueProjectTaskResult.put("iconImg", "/static/images/paojectManager/overdueProjectTask.png");
		overdueProjectTaskResult.put("value", countTask);
		return overdueProjectTaskResult;
	}

	/**
	 * @Title: getProjectInfo
	 * @description: 超期任务获取项目相关信息
	 * @param tempList
	 * @return
	 * @author: zhangjunyao
	 * @date: 2021年12月14日
	 * @modify:
	 */
	@Transactional
	public void getProjectInfo(List<Map<String, Object>> tempList) {
		String projectCodes = tempList.stream().map(map -> ConvertUtil.convertToString(map.get("projectcode")))
				.collect(Collectors.joining("','", "'", "'"));
		StringBufferProxy sql = new StringBufferProxy();
		sql.appendSingle("projectcode in ({0})", projectCodes);
		List<MpmProjectEntity> projectEntities = mpmProjectService.queryByWhere(sql.toString());
		if (CollectionUtils.isEmpty(projectEntities)) {
			return;
		}
		Map<String, MpmProjectEntity> resultMap = projectEntities.stream().collect(Collectors.toMap(
				MpmProjectEntity::getProjectcode, mpmProjectEntity -> mpmProjectEntity, (v1, v2) -> v1));
		for (Map<String, Object> mapRow : tempList) {
			String projectCode = ConvertUtil.convertToString(mapRow.get("projectcode"));
			if (resultMap.containsKey(projectCode)) {
				MpmProjectEntity mpmProjectEntity = resultMap.get(projectCode);
				mapRow.put("deptname", mpmProjectEntity.getDeptname());
				String projectlevel = mpmProjectEntity.getProjectlevel();
				mapRow.put("dispprojectlevel", datacodeCache.getValueDynamic("MpmProjectLevel", projectlevel,
						"code", "name"));
				mapRow.put("projectmanager", mpmProjectEntity.getProjectmanager());
				mapRow.put("projectmanagercode", mpmProjectEntity.getProjectmanagercode());
				mapRow.put("projectname", mpmProjectEntity.getProjectname());
			}
		}
	}

	/**
	 * @Title:
	 * @description: 策划审批通过后批量下发任务并给任务责任人发送消息提醒
	 * @param
	 * @return
	 * @author: zhangjunyao
	 * @date: 2022年03月15日
	 * @modify:
	 */
	@Transactional(rollbackFor = Exception.class)
	public void sendMessageToTaskResponsible(String projectCode, int count) {
		// 查询该项目下所有任务
		StringBufferProxy sql = new StringBufferProxy();
		sql.appendSingle(" {0} = '{1}' and {2} = 0 ", MpmProjectTaskEntity.FieldProjectcode, projectCode, MpmProjectTaskEntity.FieldState);
		List<MpmProjectTaskEntity> mpmProjectTaskEntities = this.queryByWhere(sql.toString());
		if (CollectionUtil.isEmpty(mpmProjectTaskEntities)) {
			return;
		}
		// 查询该项目立项信息
		sql.clear();
		sql.appendSingle(" {0} = '{1}' ", MpmProjectEntity.FieldProjectcode, projectCode);
		MpmProjectEntity mpmProjectEntity = mpmProjectService.queryObjectByWhere(sql.toString());
		if (ObjectUtil.isEmpty(mpmProjectEntity)) {
			return;
		}
		// 配置消息标题内容
		String projectLevel = datacodeCache.getValueDynamic("MpmProjectLevel", mpmProjectEntity.getProjectlevel(), "code", "name");
		String title = "销售项目任务派发提醒";
		// 用于封装任务实体，批量更新
		List<BasicEntity> resultList = new ArrayList<>();
		// 用于封装消息，批量插入
		List<Map<String, Object>> appList = new ArrayList<>(), sysList = new ArrayList<>();
		Map<String, Object> appMap = new HashMap<>(), sysMap = new HashMap<>();
		for (MpmProjectTaskEntity mpmProjectTaskEntity : mpmProjectTaskEntities) {
			// 更新任务状态
			mpmProjectTaskEntity.setTaskdistributedate(new Date());
			mpmProjectTaskEntity.setSubmitdate(new Date());
			mpmProjectTaskEntity.setState(9);
			mpmProjectTaskEntity.setLatestphase("结束");
			resultList.add(mpmProjectTaskEntity);
			if (count == 1) {
				// 获取任务名称，封装消息内容
				StringBufferProxy content = new StringBufferProxy();
				String taskFreStr = "";
				if (MpmSystemConst.UpdateTaskFre.EachMonth.equals(mpmProjectTaskEntity.getTaskupdatefre())) {
					taskFreStr = "更新频次为“每月”，";
				} else if (MpmSystemConst.UpdateTaskFre.EachWeek.equals(mpmProjectTaskEntity.getTaskupdatefre())) {
					taskFreStr = "更新频次为“每周”，";
				}
				content.appendSingle("您有来自【{0}级项目：{1}】的任务“{2}”，{3}请登录系统查阅任务信息。", projectLevel, mpmProjectEntity.getProjectname(), mpmProjectTaskEntity.getTaskname(), taskFreStr);
				// app推送
				appMap = MessageUtil.createMessageAppMap(mpmProjectTaskEntity.getResponsiblecode(), title, content.toString(), mpmProjectEntity.getId(),
						MpmProjectTaskEntity.tableName, 0);
				// 系统消息
				sysMap = MessageUtil.createMessageSysMap(mpmProjectTaskEntity.getResponsiblecode(), mpmProjectTaskEntity.getResponsible(), title, content.toString(),
						mpmProjectEntity.getId(), MpmProjectTaskEntity.tableName);
				// 封装
				appList.add(appMap);
				sysList.add(sysMap);
			}
		}
		// 任务实体批量更新
		this.updateBatch(resultList);
		// 消息批量插入
		cboMessageAppService.insertList(appList);
		cboMessageSysService.insertList(sysList);
	}

	/**
	 * @Title:
	 * @description: 单独下发任务并给任务责任人、里程碑及任务责任人发送消息提醒
	 * @param
	 * @return
	 * @author: zhangjunyao
	 * @date: 2022年03月17日
	 * @modify:
	 */
	@Transactional(rollbackFor = Exception.class)
	public void distributeTask(String id) {
		MpmProjectTaskEntity mpmProjectTaskEntity = this.queryById(id);
		// 若初次下发更新任务状态
		if (mpmProjectTaskEntity.getState() != 9) {
			updateTask(mpmProjectTaskEntity);
		}
		// 查询项目立项信息
		StringBufferProxy sql = new StringBufferProxy();
		sql.appendSingle(" {0} = '{1}' ", MpmProjectEntity.FieldProjectcode, mpmProjectTaskEntity.getProjectcode());
		MpmProjectEntity mpmProjectEntity = mpmProjectService.queryObjectByWhere(sql.toString());
		if (ObjectUtil.isEmpty(mpmProjectEntity)) {
			return;
		}
		// 配置消息标题内容
		String projectLevel = datacodeCache.getValueDynamic("MpmProjectLevel", mpmProjectEntity.getProjectlevel(), "code", "name");
		String title = "销售项目任务派发提醒";
		StringBufferProxy content = new StringBufferProxy();
		String taskFreStr = "";
		if (MpmSystemConst.UpdateTaskFre.EachMonth.equals(mpmProjectTaskEntity.getTaskupdatefre())) {
			taskFreStr = "更新频次为“每月”，";
		} else if (MpmSystemConst.UpdateTaskFre.EachWeek.equals(mpmProjectTaskEntity.getTaskupdatefre())) {
			taskFreStr = "更新频次为“每周”，";
		}
		content.appendSingle("您有来自【{0}级项目：{1}】的任务“{2}”，{3}请登录系统查阅任务信息。", projectLevel, mpmProjectEntity.getProjectname(), mpmProjectTaskEntity.getTaskname(), taskFreStr);
		// 给任务责任人发送消息提醒
		String taskResponsibleCode = mpmProjectTaskEntity.getResponsiblecode();
		Map<String, Object> appMap = MessageUtil.createMessageAppMap(taskResponsibleCode, title, content.toString(), mpmProjectEntity.getId(),
				MpmProjectTaskEntity.tableName, 0);
		Map<String, Object> sysMap = MessageUtil.createMessageSysMap(taskResponsibleCode, mpmProjectTaskEntity.getResponsible(), title, content.toString(),
				mpmProjectEntity.getId(), MpmProjectTaskEntity.tableName);
		cboMessageAppService.insertMap(appMap);
		cboMessageSysService.insertMap(sysMap);
	}

	/**
	 * @Title:
	 * @description: 单独下发任务时更新任务实体类
	 * @param
	 * @return
	 * @author: zhangjunyao
	 * @date: 2022年03月18日
	 * @modify:
	 */
	private void updateTask(MpmProjectTaskEntity mpmProjectTaskEntity) {
		mpmProjectTaskEntity.setTaskdistributedate(new Date());
		mpmProjectTaskEntity.setSubmitdate(new Date());
		mpmProjectTaskEntity.setState(9);
		mpmProjectTaskEntity.setLatestphase("结束");
		this.updateEntity(mpmProjectTaskEntity);
	}

	/**
	 * @author: zhangjunyao
	 * @date: 2022-03-25
	 * @description: 查询该项目是否还存在已超期的未开始/进行中的任务
	 * @modify:
	 */
	public Boolean checkTaskOverDue(String projectCode) {
		Boolean isTaskOverDue = false;
		StringBufferProxy sql = new StringBufferProxy();
		// 查询该项目是否有已超期任务
		sql.appendSingle(" {0} = '{1}' and {2} in ('{3}','{4}') and state = 9 and {5} < {6} ", MpmProjectTaskEntity.FieldProjectcode, projectCode,
				MpmProjectTaskEntity.FieldTaskstate, MpmSystemConst.TaskStateCode.TaskNotStartCode, MpmSystemConst.TaskStateCode.TaskIncompleteCode,
				MpmProjectTaskEntity.FieldPlanenddate, SQLAdapter.toDateShort(DateUtil.formatDate(new Date())));
		int count = this.getCount(sql.toString());
		if (count > 0) {
			isTaskOverDue = true;
		}
		return isTaskOverDue;
	}
	/**
	 * @Title:
	 * @description: 系统部监管页面获取客户决策分析数据
	 * @param
	 * @return
	 * @author: houyuhang
	 * @date: 2021年03月26日
	 * @modify:
	 */
	public List<Map<String,Object>> queryTaskForSystem(Map<String, Object> paraMap) {
		String projectcode = ConvertUtil.convertToString(paraMap.get("projectcode"));
		StringBufferProxy sql = new StringBufferProxy();
		if(paraMap.containsKey("needsupport") && !ObjectUtil.isEmpty(paraMap.get("needsupport"))) {
			String needsupport = ConvertUtil.convertToString(paraMap.get("needsupport"));
			sql.appendSingle(" {0} = '{1}' and ", MpmProjectTaskEntity.FieldNeedsupport,needsupport);
		}
		List<Map<String, Object>> mpmSystemTasknameList = datacodeCache.getCodeListMap("MpmSystemTaskname", "", "sortcode");
		String taskName = mpmSystemTasknameList.stream().map(item -> "'" + ConvertUtil.convertToString(item.get("name")) + "'").collect(Collectors.joining(","));
		sql.appendSingle(" projectcode = '{0}' and state = 9 and {1} is not null and {2} in ({3}) ", projectcode, MpmProjectTaskEntity.FieldPost, MpmProjectTaskEntity.FieldTaskname, taskName);
		List<MpmProjectTaskEntity> tempList = this.queryByWhere(sql.toString());
		// 八个任务按照编码排序排序
		List<Map<String,Object>> sortableTempList = new ArrayList<>();
		Map<String, List<MpmProjectTaskEntity>> tempMap = tempList.stream().collect(Collectors.groupingBy(item -> ConvertUtil.convertToString(item.getTaskname())));
		for (Map<String,Object> mpmSystemTaskname : mpmSystemTasknameList) {
			String systemTaskname = ConvertUtil.convertToString(mpmSystemTaskname.get("name"));
			if (!CollectionUtil.isEmpty(tempMap.get(systemTaskname))) {
				sortableTempList.add(tempMap.get(systemTaskname).get(0).convertToMap());
			}
		}
		return sortableTempList;
	}
	/**
	 * @Title:
	 * @description: 判断A级项目（非电商、其他）中该任务（为8个系统部监管任务之一）是否已存在
	 * @param
	 * @return
	 * @author: houyuhang
	 * @date: 2022年03月26日
	 * @modify:
	 */
	public Boolean haveSystemTask(BasicEntity entity) {
		// A级项目（非电商、其他）
		String projectcode = ConvertUtil.convertToString(entity.getValue("projectcode"));
		Boolean projectFlag = mpmProjectMilepostService.judgeProjectALevel(projectcode);
		// 任命名称为8个系统部监管任务之一
		String taskname = ConvertUtil.convertToString(entity.getValue("taskname"));
		List<Map<String, Object>> mpmSystemTasknameList = datacodeCache.getCodeListMap("MpmSystemTaskname", "", "sortcode");
		Boolean taskFlag = false;
		for(Map<String, Object> mpmSystemTaskname : mpmSystemTasknameList) {
			if (ConvertUtil.convertToString(mpmSystemTaskname.get("name")).equals(taskname)) {
				taskFlag = true;
				break;
			}
		}
		if (projectFlag && taskFlag) {
			StringBufferProxy sql = new StringBufferProxy();
			sql.appendSingle(" projectcode = '{0}' and taskname = '{1}' ",projectcode, taskname);
			if (entity.getId() > 0) {
				sql.appendSingle(" and id != '{0}' ", entity.getId());
			}
			List<MpmProjectTaskEntity> mpmProjectTaskEntities = this.queryByWhere(sql.toString());
			return !CollectionUtil.isEmpty(mpmProjectTaskEntities);
		}
		return false;
	}
	/**
	 * @description: 查询该相关方负责任务数量
	 * @author: houyuhang
	 * @date: 2022年04月18日
	 * @modify:
	 */
	public void queryTaskNum(List<Map<String, Object>> tempList) {
		if (CollectionUtil.isEmpty(tempList)) {
			return;
		}
		String usercode = tempList.stream().map(item -> "'" + ConvertUtil.convertToString(item.get("usercode")) + "'").collect(Collectors.joining(","));
		String taskState = "'" + MpmSystemConst.TaskStateCode.TaskNotStartCode + "','" + MpmSystemConst.TaskStateCode.TaskIncompleteCode + "'";
		StringBufferProxy sql = new StringBufferProxy();
		// 查找已下发的且任务状态为未开始和进行中的任务数量
		sql.appendSingle(" {0} in ({1}) and {2} in ({3}) and state = 9 ", MpmProjectTaskEntity.FieldResponsiblecode, usercode, MpmProjectTaskEntity.FieldTaskstate, taskState);
		List<MpmProjectTaskEntity> mpmProjectTaskEntities = this.queryByWhere(sql.toString());
		Map<String, List<MpmProjectTaskEntity>> mpmProjectTaskMap = mpmProjectTaskEntities.stream().collect(Collectors.groupingBy(MpmProjectTaskEntity::getResponsiblecode));
		for (Map<String, Object> temp : tempList) {
			String usercodeTemp = ConvertUtil.convertToString(temp.get("usercode"));
			List<MpmProjectTaskEntity> taskTemp = mpmProjectTaskMap.get(usercodeTemp);
			temp.put("tasknum", CollectionUtil.isEmpty(taskTemp) ? 0 : taskTemp.size());
		}
	}


	@Transactional
	public void sendTaskChangeMessage(String usercodes,String projectcode,String taskname,long taskid) {
		MpmProjectEntity mpmProjectEntity = mpmProjectService.queryObjectByWhere(" projectcode = '"+projectcode+"'");
		if(mpmProjectEntity==null) {
			return;
		}
		String projectname = mpmProjectEntity.getProjectname();
		projectname = projectname.endsWith("项目") ? projectname : (projectname + "项目");
		taskname = taskname.endsWith("任务") ? taskname : (taskname + "任务");
		String content = "您关注的"+projectname+","+taskname+"任务有更新/变动，请登录销售项目系统查阅。";
		String title = "销售项目关注提醒";
		List<CboUserEntity> cboUserEntities = cboUserService.queryByWhere("code in ("+usercodes+")");
		List<Map<String,Object>> appList = new ArrayList<>();
		List<Map<String,Object>> sysList = new ArrayList<>();
		for(CboUserEntity userEntity:cboUserEntities) {
			Map<String,Object> appTemp = mpmProjectService.insertMessageApp(userEntity.getCode(),title,content,taskid,MpmProjectTaskEntity.tableName,0);
			Map<String,Object> sysTemp = mpmProjectService.insertMessageSys(userEntity.getCode(),userEntity.getName(),title,content,taskid,MpmProjectTaskEntity.tableName);
			appList.add(appTemp);
			sysList.add(sysTemp);
		}
		if(appList!=null && appList.size()>0) {
			cboMessageAppService.insertList(appList);
			cboMessageSysService.insertList(sysList);
		}
	}
	@SneakyThrows
	@Override
	public void setDispFields(Map<String, Object> mapRow, DatacodeCache datacodeCache) {
		super.setDispFields(mapRow,datacodeCache);
		String temp;
		// 为手机端拼接字符串 任务tasktarget去掉空格
		if (mapRow.get("tasktarget") != null) {
			temp = mapRow.get("tasktarget").toString();
			mapRow.put("disptasktarget", temp.trim());
		}
		// 未开始、进行中且已下发的任务，超过计划完成日期，解析为超期
		if (mapRow.get("taskstate") != null) {
			temp = mapRow.get("taskstate").toString();
			mapRow.put("disptaskstateindex", datacodeCache.getValueDynamic("MpmTaskState", temp, "code", "name"));
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
			Date date = simpleDateFormat.parse(simpleDateFormat.format(new Date()));
			if (MpmSystemConst.UndoneTaskCode.contains(temp) && !ObjectUtil.isEmpty(mapRow.get("planenddate")) && date.compareTo(ConvertUtil.convertToDate(mapRow.get("planenddate"))) > 0 && "9".equals(ConvertUtil.convertToString(mapRow.get("state")))) {
				mapRow.put("disptaskstateindex", datacodeCache.getValueDynamic("MpmTaskState", MpmSystemConst.TaskStateCode.TaskOverdueCode, "code", "name"));
			}
		}
	}
	/**
	 * @description: 同步更新任务的里程碑名称
	 * @author: houyuhang
	 * @date: 2022年09月15日
	 * @modify:
	 */
	public List<MpmProjectTaskEntity> updateTaskname(Map<String, Object> map) {
		StringBufferProxy sql = new StringBufferProxy();
		sql.appendSingle(" enabled = 1 and milepostcode = '{0}' ", ConvertUtil.convertToString(map.get("operatecode")));
		List<MpmProjectTaskEntity> mpmProjectTaskEntities = this.queryByWhere(sql.toString());
		for (MpmProjectTaskEntity mpmProjectTaskEntity : mpmProjectTaskEntities) {
			mpmProjectTaskEntity.setMilepostname(ConvertUtil.convertToString(map.get("milepostname")));
		}
		return mpmProjectTaskEntities;
	}
    /**
     * @description: 任务更新时间前一天对任务责任人发送更新提醒
     * @author: houyuhang
     * @date: 2022年09月16日
     * @modify:
     */
    public void sendTaskUpdateFreApp(List<Map<String, Object>> appMap, List<Map<String, Object>> sysMap) {
        // 查询任务及相关联的项目信息
        StringBufferProxy sql = new StringBufferProxy();
        sql.appendSingle(" mpmprojecttask.state = 9 and taskstate in ({0}) and (taskupdatefre = '{1}' and {2} = {3} or taskupdatefre = '{4}' and {5} = {6}) ", MpmSystemConst.TaskStateCode.TaskNotStartCode + "," + MpmSystemConst.TaskStateCode.TaskIncompleteCode
            , MpmSystemConst.UpdateTaskFre.EachMonth, SQLAdapter.toChar(MpmProjectTaskEntity.FieldTaskupdatedate + " + 30, 'yyyy-MM-dd'"), SQLAdapter.toChar(SQLAdapter.getDate() + ", 'yyyy-MM-dd'")
                , MpmSystemConst.UpdateTaskFre.EachWeek, SQLAdapter.toChar(MpmProjectTaskEntity.FieldTaskupdatedate + "+ 7, 'yyyy-MM-dd'"), SQLAdapter.toChar(SQLAdapter.getDate() + ", 'yyyy-MM-dd'"));
        List<Map<String, Object>> mpmProjectTaskList = this.queryMapByWhere(sql.toString(), "queryTaskUpdateFre");
        if (CollectionUtil.isEmpty(mpmProjectTaskList)) {
            return;
        }
        for (Map<String, Object> mpmProjectTaskMap : mpmProjectTaskList) {
            // 配置消息标题内容
            String projectLevel = datacodeCache.getValueDynamic("MpmProjectLevel", ConvertUtil.convertToString(mpmProjectTaskMap.get("projectlevel")), "code", "name");
            String title = "销售项目任务更新提醒";
            StringBufferProxy content = new StringBufferProxy();
            content.appendSingle("您所负责的【{0}级项目：{1}】的任务“{2}”，已经到达更新时间，请及时前往更新。", projectLevel, ConvertUtil.convertToString(mpmProjectTaskMap.get("mpmprojectname")), ConvertUtil.convertToString(mpmProjectTaskMap.get("taskname")));
            String taskResponsibleCode = ConvertUtil.convertToString(mpmProjectTaskMap.get("responsiblecode"));
            // 给任务责任人发送更新频次修改消息提醒
            appMap.add(MessageUtil.createMessageAppMap(taskResponsibleCode, title, content.toString(), ConvertUtil.convertToLong(mpmProjectTaskMap.get("mpmid")),
                    MpmProjectTaskEntity.tableName, 0));
            sysMap.add(MessageUtil.createMessageSysMap(taskResponsibleCode, ConvertUtil.convertToString(mpmProjectTaskMap.get("responsible")), title, content.toString(),
                    ConvertUtil.convertToLong(mpmProjectTaskMap.get("mpmid")), MpmProjectTaskEntity.tableName));
        }
    }
    /**
     * @description: 当差距与改进或任务反馈完成时，调用此方法将更新时间置为当前日期
     * @author: houyuhang
     * @date: 2022年09月16日
     * @modify:
     */
    @Transactional
    public void updateTaskUpdateDate(String taskid) {
        MpmProjectTaskEntity mpmProjectTaskEntity = this.queryById(taskid);
        if (ObjectUtil.isEmpty(mpmProjectTaskEntity)) {
            return;
        }
        mpmProjectTaskEntity.setTaskupdatedate(new Date());
		Map<String, Object> taskMap = mpmProjectTaskEntity.convertToMap();
		taskMap.put("dateupdateflag", 1);
        this.update(taskMap);
    }
	/**
	 * @description: 当差距与改进或任务反馈完成时，调用此方法将更新时间置为当前日期
	 * @author: houyuhang
	 * @date: 2022年09月16日
	 * @modify:
	 */
	public List<Map<String, Object>> queryTreeList(Map<String, Object> paraMap) {
		// 获取里程碑信息
		StringBufferProxy sql = new StringBufferProxy();
		sql.appendSingle(" enabled = 1 and projectcode = '{0}' order by sortcode asc,planfinishtime asc,id asc  ", paraMap.get("qry_projectcode"));
		List<Map<String, Object>> milepostList = mpmProjectMilepostService.queryMapByWhere(sql.toString());
		// 如果里程碑为空，直接返回
		if (CollectionUtil.isEmpty(milepostList)) {
			return new ArrayList<>();
		}
		Map<String, List<Map<String, Object>>> operatecodeMap = milepostList.stream().collect(Collectors.groupingBy(item -> ConvertUtil.convertToString(item.get("operatecode"))));
		// 获取任务信息
		String operatecode = milepostList.stream().map(item -> ConvertUtil.convertToString(item.get("operatecode"))).collect(Collectors.joining("','", "'", "'"));
		sql.clear();
		sql.appendSingle(" enabled = 1 and milepostcode in ({0}) and (EXISTS (SELECT 1 FROM mpmprojectsquared WHERE mpmprojecttask.id = mpmprojectsquared.taskid) OR " +
				"EXISTS (SELECT 1 FROM MPMPROJECTFISHFIRST WHERE mpmprojecttask.id = MPMPROJECTFISHFIRST.taskid)) order by sortcode asc, planenddate asc, planstartdate asc, id asc ", operatecode);
		List<Map<String, Object>> taskList = this.queryMapByWhere(sql.toString());
		// 如果任务为空,直接返回
		if (CollectionUtil.isEmpty(taskList)) {
			return new ArrayList<>();
		}
		// 获取任务的milepostcode，得到需要加载的里程碑信息
		List<String> milepostcodeList = taskList.stream().map(item -> ConvertUtil.convertToString(item.get("milepostcode"))).distinct().collect(Collectors.toList());
		List<Map<String, Object>> tempMilepostList = new ArrayList<>();
		// 为里程碑拼接parentid、name、label
		for (String milepostStr : milepostcodeList) {
			Map<String, Object> milepostMap = operatecodeMap.get(milepostStr).get(0);
			milepostMap.put("parentid", 0);
			milepostMap.put("name", milepostMap.get("milepostname"));
			milepostMap.put("label", milepostMap.get("milepostname"));
			tempMilepostList.add(milepostMap);
		}
		// 为任务拼接parentid、name、label
		for (Map<String, Object> taskMap : taskList) {
			taskMap.put("parentid", operatecodeMap.get(taskMap.get("milepostcode")).get(0).get("id"));
			taskMap.put("name", taskMap.get("taskname"));
			taskMap.put("label", taskMap.get("taskname"));
		}
		List<Map<String, Object>> listNewModule = new ArrayList<>();
		listNewModule.addAll(tempMilepostList);
		listNewModule.addAll(taskList);
		return listNewModule;
	}
	/**
	 * @Title: queryMilepostAllFinished
	 * @description: 判断里程碑是否全部完成，如果全部完成则将schedulestate变更为“复盘阶段”
	 * 判断里程碑是否未全部完成，
	 * @return
	 * @author: houyuhang
	 * @date: 2022年12月27日
	 * @modify:
	 */
	public void queryMilepostAllFinished(MpmProjectEntity mpmProjectEntity) {
		// 判断里程碑是否全部完成，如果全部完成则将项目状态变更为“复盘阶段”
		StringBufferProxy whereSql = new StringBufferProxy();
		// 查询里程碑是否存在,如果里程碑不存在return，里程碑存在判断里程碑是否全部完成
		whereSql.appendSingle(" projectcode = '{0}' and enabled = 1 ", mpmProjectEntity.getProjectcode());
		List<MpmProjectMilepostEntity> mpmProjectMilepostEntities = mpmProjectMilepostService.queryByWhere(whereSql.toString());
		if (CollectionUtil.isEmpty(mpmProjectMilepostEntities)) {
			return;
		}
		// 查询里程碑是否全部完成
		whereSql.clear();
		whereSql.appendSingle(" projectcode = '{0}' and enabled = 1 and milepoststate = '{1}' ", mpmProjectEntity.getProjectcode(), MpmSystemConst.MilepostStateCode.MilepostIncompleteCode);
		List<MpmProjectMilepostEntity> mpmProjectMilepostEntities1 = mpmProjectMilepostService.queryByWhere(whereSql.toString());
		MpmProjectSaleEntity mpmProjectSaleEntity = mpmProjectSaleService.queryById(ConvertUtil.convertToString(mpmProjectEntity.getId()));
		if (ObjectUtil.isEmpty(mpmProjectSaleEntity)) {
			return;
		}
		if (CollectionUtil.isEmpty(mpmProjectMilepostEntities1)) {
			mpmProjectEntity.setSchedulestate(MpmSystemConst.MpmScheduleState.ReviewState);
			// 如果项目等级为A级且为非招标项目，则所有任务完成后赋值meetenddate
			if (MpmSystemConst.ProjectLevel.A.equals(mpmProjectEntity.getProjectlevel()) && (MpmSystemConst.PurchasePattern.noBid.equals(mpmProjectSaleEntity.getPurchasepattern()) || MpmSystemConst.PurchasePattern.otherNoBid.equals(mpmProjectSaleEntity.getPurchasepattern()))) {
				Calendar calendar = Calendar.getInstance();
				calendar.setTime(new Date());
				calendar.add(Calendar.DATE, -7);
				ConvertTimeUtil.convertToThisWeekSunday(calendar);
				mpmProjectEntity.setMeetenddate(calendar.getTime());
			}
			mpmProjectService.updateEntity(mpmProjectEntity);
		} else if (MpmSystemConst.MpmScheduleState.ReviewState == mpmProjectEntity.getSchedulestate()) {
			mpmProjectEntity.setSchedulestate(MpmSystemConst.MpmScheduleState.ExeState);
			// 如果项目等级为A级且不存在开标日期,由于存在新增的里程碑，需要清空会议完成日期
			if (MpmSystemConst.ProjectLevel.A.equals(mpmProjectEntity.getProjectlevel()) && (MpmSystemConst.PurchasePattern.noBid.equals(mpmProjectSaleEntity.getPurchasepattern()) || MpmSystemConst.PurchasePattern.otherNoBid.equals(mpmProjectSaleEntity.getPurchasepattern()))) {
				mpmProjectEntity.setMeetenddate(null);
			}
			mpmProjectService.updateEntity(mpmProjectEntity);
		}
	}
	/***
	 * @description: 发送里程碑单独修改消息
	 * @return void
	 * @author: houyuhang
	 * @date: 2023/02/11
	 * @modify:
	 */
	public void singleChangeTaskSendMessage(Map<String, Object> map) throws Exception {
		// 如果是不走审批单独变更一个任务(map中存有fromindex标记)，直接发送变更信息
		if (!map.containsKey("fromindex")) {
			return;
		}
		MpmProjectTaskEntity oldEntity = this.queryById(ConvertUtil.convertToString(map.get("id")));
		MpmProjectEntity mpmProjectEntity = mpmProjectService.queryObjectByWhere(" projectcode='" + oldEntity.getProjectcode() + "'");
		if (ObjectUtil.isEmpty(oldEntity) || ObjectUtil.isEmpty(mpmProjectEntity)) {
			return;
		}
		// 使用basechangelog表获取变更内容
		Map<String, Object> changeMap = new HashMap<String, Object>();
		changeMap.put("topsourcetype", MpmProjectPlanEntity.tableName);
		changeMap.put("topsourceid", ConvertUtil.convertToString(map.get("id")));
		changeMap.put("sourcetype", MpmProjectTaskEntity.tableName);
		changeMap.put("sourceid", ConvertUtil.convertToString(map.get("id")));
		changeMap.put("newmap", map);
		changeMap.put("oldmap", oldEntity.convertToMap());
		changeMap.put("baselogoperatetype", MpmSystemConst.BaseLogOperateTypeEnum.Edit);
		changeMap.put("version", "1");
		Map<String, Object> changeResMap = this.getMainChangeLogEntity(changeMap);
		if (ObjectUtil.isEmpty(changeResMap)) {
			return;
		}
		// 获取需要发送消息的人员(里程碑为里程碑责任人、项目经理且剔除发起修改的人、任务为任务责任人、里程碑责任人、项目经理且剔除发起修改的人)
		List<Map<String, String>> receiverList = mpmProjectMilepostService.queryMessageUser(map, mpmProjectEntity, ConvertUtil.convertToString(map.get("singlechangeuser")), MpmProjectTaskEntity.tableName);
		if (CollectionUtil.isEmpty(receiverList)) {
			return;
		}
		String title = "销售项目任务变更通知";
		String projectLevel = datacodeCache.getValueDynamic("MpmProjectLevel", mpmProjectEntity.getProjectlevel(), "code", "name");
		StringBufferProxy content = new StringBufferProxy();
		content.appendSingle("【{0}级项目：{1}】{2}任务{3}请知悉。", projectLevel, mpmProjectEntity.getProjectname(), ConvertUtil.convertToString(map.get("taskname")), mpmProjectMilepostService.getMilepostInfoDetail(changeResMap));
		List<Map<String, Object>> appList = new ArrayList<>(), sysList = new ArrayList<>();
		for (Map<String, String> receiver : receiverList) {
			appList.add(MessageUtil.createMessageAppMap(ConvertUtil.convertToString(receiver.get("usercode")), title, content.toString(), mpmProjectEntity.getId(),
					MpmProjectTaskEntity.tableName, 0));
			sysList.add(MessageUtil.createMessageSysMap(ConvertUtil.convertToString(receiver.get("usercode")), ConvertUtil.convertToString(receiver.get("username")), title, content.toString(),
					mpmProjectEntity.getId(), MpmProjectTaskEntity.tableName));
		}
		cboMessageAppService.insertList(appList);
		cboMessageSysService.insertList(sysList);
	}
	/***
	 * @description: 任务级联删除
	 * @return void
	 * @author: houyuhang
	 * @date: 2023/02/24
	 * @modify:
	 */
	public void deleteCascadeTask(List<MpmProjectTaskEntity> mpmProjectTaskEntities) {
		String taskStr = mpmProjectTaskEntities.stream().filter(item -> !MpmSystemConst.TaskStateCode.TaskNotStartCode.equals(item.getTaskstate())).map(item -> ConvertUtil.convertToString(item.getId())).collect(Collectors.joining(","));
		// 如果删除的时未开始的任务，不需要级联删除任务反馈等信息
		if (StringUtil.isEmpty(taskStr)) {
			return;
		}
		StringBufferProxy sqltask = new StringBufferProxy();
		sqltask.appendSingle(" taskid in ({0}) ", taskStr);
		// 删除任务对应的任务反馈，差距与改进信息
		mpmProjectTaskFeedbackService.deleteByWhere(sqltask.toString());
		// 删除任务对应的任务关闭信息
		mpmProjectTaskCloseService.deleteByWhere(sqltask.toString());
	}
	/**
	 * @description: 处理拼接in超过1000问题
	 * @return
	 * @author: houyuhang
	 * @date: 2023-05-26
	 * @modify:
	 */
	public List<List<Map<String, Object>>> splitInList(List<Map<String, Object>> projectList) {
		List<List<Map<String, Object>>> splitList = new ArrayList<>();
		int toIndex = 1000;
		for (int i = 0; i < projectList.size(); i+= 1000) {
			if (i + 1000 > projectList.size()) {
				toIndex = projectList.size() - i;
			}
			splitList.add(projectList.subList(i, i + toIndex));
		}
		return splitList;
	}
}
